"use client";

import { memo, useCallback, useEffect, useRef, useState } from "react";
import type { ReactNode, FC } from "react";
import { Slider, message } from "antd";

import styles from "./style.module.scss";
import { shallowEqualApp, useAppDispatch, useAppSelector } from "@/store/hooks";
import { getPlayUrl, formatTime } from "@/utils/format";
import { changeCurrentSong, setLyric, setPlayMode } from "../store/player";

interface IProps {
  children?: ReactNode;
}

const PlayerBar: FC<IProps> = (props) => {
  const [isPlaying, setIsPlaying] = useState(false);
  const [progress, setProgress] = useState(0);
  const [currentTime, setCurrentTime] = useState(0);
  const [isLock, setIsLock] = useState(true);
  const audioRef: any = useRef(null);

  const dispatch = useAppDispatch();

  const { currentSong, lyric, lyricIndex, playMode } = useAppSelector(
    (state) => ({
      currentSong: state.player.currentSong,
      lyric: state.player.lyric,
      lyricIndex: state.player.lyricIndex,
      playMode: state.player.playMode,
    }),
    shallowEqualApp
  );

  // 总时间
  const songTime = currentSong.dt / 1000;

  // 当目前的歌曲改变时 ， 重新获取 src
  useEffect(() => {
    if (audioRef.current) {
      audioRef.current.src = getPlayUrl(currentSong.id);
    }
  }, [currentSong]);

  // 播放/ 暂停
  const handlePlayBtn = useCallback(() => {
    setIsPlaying(!isPlaying);
  }, [isPlaying]);

  // 提取 播放/暂停的方法,依赖 currentSong
  // 实现 即使 切换歌曲 ，播放状态同步
  useEffect(() => {
    if (audioRef.current) {
      if (isPlaying) {
        audioRef.current.play();
      } else {
        audioRef.current.pause();
      }
    }
  }, [isPlaying, currentSong]);

  // 模式切换
  const handleLoopClick = useCallback(() => {
    let newState = playMode + 1;
    if (newState > 2) newState = 0;
    dispatch(setPlayMode(newState));
    console.log(playMode);
  }, [playMode]);

  // 当 audio time 变化时同步到 自定义组件
  const handleOnTimeUpdate = () => {
    setCurrentTime(audioRef.current.currentTime);
    setProgress((audioRef.current.currentTime / songTime) * 100);
    if (lyric.length == 0) return;
    let index = lyric.length - 1;
    let cts = audioRef.current.currentTime * 1000;
    // 找到目前的歌词
    for (let i = 0; i < lyric.length; ++i) {
      if (lyric[i].time > cts) {
        break;
      }
      index = i;
    }
    // 不同再更新
    if (index !== lyricIndex) {
      dispatch(setLyric(index));
      // 在全局样式中修改了 message 的 样式
      message.open({
        content: lyric[index].lyric,
        key: "lyric", // 设置相同的 key , 会替换之前的
        duration: 0, // 不消失
      });
    }
  };

  // 点击触发进度条
  const handleonChangeComplete = useCallback((val: number) => {
    // setProgress(val);
  }, []);

  // Slider 设置 value 后成为 受控组件，需要onChange 来响应
  const handleSliderChange = useCallback(
    (val: number) => {
      if (val >= 0 && val <= 100 && isFinite(songTime)) {
        setProgress(val);
        let ct = (val * songTime) / 100;
        if (isFinite(ct)) {
          setCurrentTime(ct);
          audioRef.current.currentTime = ct;
        }
      }
    },
    [songTime]
  );

  // audio
  // 切换目前的歌曲 （上/下一首）
  const handleMusicChange = useCallback((isNext: boolean) => {
    dispatch(changeCurrentSong(isNext));
  }, []);

  // 当歌曲结束时
  const handleOnEnded = useCallback(() => {
    if (playMode === 1) {
      audioRef.current.currentTime = 0;
    } else {
      dispatch(changeCurrentSong(true));
    }
  }, []);

  return (
    <div className={styles.playerBarAWrapper}>
      <div
        className={`${styles.playerBarWrapper} ${styles.visible} ${
          isLock ? styles.lock : styles.nolock
        }`}
      >
        <div className={`${styles.bg} sprite_player`}></div>
        <div className={styles.playerBarContentWrapper}>
          <div className={styles.btns}>
            <a
              title="上一首"
              className={`${styles.prev} sprite_player`}
              onClick={() => handleMusicChange(true)}
            ></a>
            <a
              title="播放/暂停"
              className={`sprite_player ${
                isPlaying ? styles.play : styles.pause
              }`}
              onClick={handlePlayBtn}
            ></a>
            <a
              title="下一首"
              className={`${styles.nxt} sprite_player`}
              onClick={() => handleMusicChange(false)}
            ></a>
          </div>
          <div className={styles.image}>
            <img src={currentSong.al?.picUrl} />
            <a className="sprite_player"></a>
          </div>
          <div className={styles.playerWrapper}>
            <div className={styles.song_info}>
              <a href="">{currentSong?.name}</a>
              <a>
                {currentSong && currentSong.ar && currentSong.ar.length > 0
                  ? currentSong.ar[0].name
                  : "未知歌手"}
              </a>
              <a className={`sprite_player ${styles.from_songs}`}></a>
            </div>
            <Slider
              tooltip={{ formatter: null }}
              value={progress}
              step={0.5}
              onChangeComplete={handleonChangeComplete}
              onChange={handleSliderChange}
            />
            <span>
              <em>{formatTime(currentTime)}</em> / {formatTime(songTime)}
            </span>
          </div>
          <div className={styles.operWrapper}>
            <a className={styles.show}></a>
            <a className={`sprite_player ${styles.like}`}></a>
            <a className={`sprite_player ${styles.share}`}></a>
          </div>
          <div className={styles.ctrlWrapper}>
            <a className={`sprite_player ${styles.voice}`}></a>
            <a
              className={`sprite_player ${styles["loop" + playMode]}`}
              onClick={handleLoopClick}
            ></a>
            <span className={styles.play_list}>
              <span className="sprite_player"></span>
              <a className="sprite_player"></a>
            </span>
            <a className={`${styles.quality} audio_quality`}></a>
          </div>
        </div>
        <audio
          id="audio"
          ref={audioRef}
          onTimeUpdate={handleOnTimeUpdate}
          onEnded={handleOnEnded}
          preload="auto"
        />
        <div className={`${styles.vb} sprite_player`}>
          <a
            className="sprite_player"
            onClick={(e) => {
              e.preventDefault(); // 阻止默认行为
              setIsLock(!isLock);
            }}
          ></a>
        </div>
        <div className={`${styles.bg_2} sprite_player`}></div>
      </div>
    </div>
  );
};

export default memo(PlayerBar);
